package com.slashvision.im.chat

import android.os.Bundle
import android.os.CountDownTimer
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.rememberCompositionContext
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.fragment.app.Fragment
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import com.slashvision.im.*
import com.slashvision.im.eventbus.Bus
import com.slashvision.im.tool.ClipboardUtil
import com.slashvision.im.tool.TimeUtil
import com.slashvision.stylist.common.eventbus.BusKey
import com.slashvision.stylist.im.RecordVoiceUtil
import io.openim.android.sdk.OpenIMClient
import io.openim.android.sdk.enums.MessageType
import io.openim.android.sdk.listener.OnBase
import io.openim.android.sdk.listener.OnMsgSendCallback
import io.openim.android.sdk.models.ConversationInfo
import io.openim.android.sdk.models.Message
import io.openim.android.sdk.models.SoundElem
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import kotlin.coroutines.coroutineContext

/**
 * author : lizhenxin
 *  date  : 2021/11/16
 *  desc  :
 */
/**
 * @desc:
 * @author: LiZhenxin
 * @create:
 * update
 **/
class ChatViewModel : ViewModel() {

    private val TAG = this.TAG()

    private val mRepository by lazy { ChatRepository() }

    private val mContext = ContextUtil.getContext()

    private val mMsgManager = OpenIMClient.getInstance().messageManager
    private val mConvManager = OpenIMClient.getInstance().conversationManager

    companion object {
        val extentInputList = mutableListOf<ExtendInputBean>(
            ExtendInputBean("照片", R.drawable.ic_chat_photo) {
//                LaunchUtils.startActivity(ContextUtil.getContext(), PicSelectActivity::class.java)
            },
            ExtendInputBean("拍照", R.drawable.ic_chat_camera) {
                val path = "${TimeUtil.NOW()}.jpg"
                Bus.with<String>(BusKey.TAKE_PHOTO).post(path)
            },
            ExtendInputBean("录像", R.drawable.ic_chat_video) {
                val path = "${TimeUtil.NOW()}.mp4"
                Bus.with<String>(BusKey.TAKE_VIDEO).post(path)
            }
        )
    }


    /***
     * 跳转到聊天页面。初始化uistate
     * @param fragment  当前fragment
     * @param friendId  朋友id
     * @param friendName 朋友名字
     */
    fun toChatFragment(fragment: Fragment, friendId: String, friendName: String) {
//        initUiState(friendId, friendName)
        mMsgManager.getHistoryMessageList(object : OnBase<List<Message>> {
            override fun onError(code: Long, error: String?) {
            }

            override fun onSuccess(data: List<Message>?) {
                data?.let {
                    initUiState(friendId, friendName, it)
                }
                /*fragment.findNavController()
                    .navigate(R.id.action_wearerFragment_to_chatFragment)*/
            }
        }, friendId, null, null, Int.MAX_VALUE)

    }




    /**
     * 点击用户头像
     */
    fun onClickAvatar() {

    }

    // 当前聊天朋友的id
    private var mFriendId = ""
    fun getFriendId() = mFriendId

    // 当前聊天朋友的name
    private var mFriendName = ""
    fun getFriendName() = mFriendName

    // 当前聊天页面uiState
    val currentUIState by lazy { ChatUiState("", "", mutableStateListOf()) }

    fun initUiState(id: String, name: String, initMsgs: List<Message>) {
        mFriendId = id
        mFriendName = name
        currentUIState.apply {
            SLog.d(TAG, "set data: ${initMsgs.size}")
            friendId = id
            friendName = name
            setMsgList(initMsgs)
        }
    }


    /**
     * 最近会话
     */
    private val _recentConv: MutableLiveData<List<ConversationInfo>> = MutableLiveData()
    val recentConv: LiveData<List<ConversationInfo>> get() = _recentConv
    fun getRecentConversation() {
        _recentConv.postValue(mutableListOf())
        SLog.d(TAG_IM, "正在获取最近会话")
        mConvManager.getAllConversationList(object : OnBase<List<ConversationInfo>> {
            override fun onError(code: Long, error: String?) {
                SLog.e(this.TAG(), "获取最近会话出错： ${code}   ${error}")
            }

            override fun onSuccess(data: List<ConversationInfo>?) {
                data?.let {
                    SLog.d(this.TAG(), "最近会话${it.size}个")
                    _recentConv.postValue(it.toMutableList())
                }
            }
        })
    }


    /**
     * 好友列表
     */
    /*private val _allFriends: MutableLiveData<List<UserProperty>> = MutableLiveData()
    val allFriends: LiveData<List<UserProperty>> get() = _allFriends
    fun getAllFriends() {
        mRepository.getAllFriend {
            _allFriends.postValue(listOf())
            _allFriends.postValue(it.toMutableList())
        }
    }*/


    /**
     * 发送消息
     */
    fun sendMessage(msg: Message) {
        SLog.d(TAG_IM, "${msg.sendID}到${getFriendId()}发送消息")
        mMsgManager.sendMessage(
            object : OnMsgSendCallback {
                override fun onError(code: Long, error: String?) {
                    SLog.d(TAG_IM, "${msg.sendID}到${getFriendId()}发送失败：${code}，${error.toString()}")
                }

                override fun onSuccess(s: String?) {
                    s?.let {
                        SLog.d(TAG_IM, "${msg.sendID}到${getFriendId()}发送成功：${it}")
                    }
                }

                override fun onProgress(progress: Long) {
                    SLog.d(TAG_IM, "${msg.sendID}到${getFriendId()}发送中：${msg.content}")
                }
            }, msg, getFriendId(), null, false
        )
    }


    /**
     * 设置会话已读
     */
    fun setConvRead(friendId: String = getFriendId()) {
        mRepository.setConvRead(friendId)
    }


    /**
     * 设置消息已读
     */
    fun setMsgRead(msgIds: List<String>, friendId: String = getFriendId()) {
        mRepository.setMsgRead(friendId, msgIds)
    }


    /**
     * 点击消息的操作
     */
    fun onMessageClick(m: Message, navController: NavHostController):Boolean {
        return when (m.contentType) {
            MessageType.VOICE -> {
                var state = false
                if (getVoicePlayState()) {
                    stopPlayVoice(m)
                    state = false
                } else {
                    startPlayVoice(m)
                    state = true
                }
                state
            }
            MessageType.PICTURE -> {
                navController.navigate("${ROUTE_IMAGE_PREVIEW}?isNet=${true}&path=${m.pictureElem.sourcePicture.url}")
                false
            }
            MessageType.VIDEO -> {
                SLog.d(
                    TAG_IM,
                    "url: ${m.videoElem.videoUrl} \n path: ${m.videoElem.videoPath}\n exist: ${
                        File(
                            m.videoElem.videoPath
                        ).exists()
                    }"
                )
                val bundle = Bundle().apply {
                    putString(KEY_URL, m.videoElem.videoUrl)
                    putString(KEY_PATH, m.videoElem.videoPath)
                }
                /*LaunchUtils.startActivity(
                    launchAct = VideoPreviewActivity::class.java,
                    bundle = bundle
                )*/
                false
            }
            else -> false
        }
    }

    /**
     * 复制消息
     */
    fun onCopyMessage(msg: Message) {
        ClipboardUtil.copy2Clipboard(msg.content)
        ContextUtil.getContext().toastShort("已复制到剪贴板")
    }

    /**
     * 删除消息
     */
    fun onDeleteMessage(msg: Message) {
        mMsgManager.deleteMessages(object :
            OnBase<String> {
            override fun onError(code: Long, error: String?) {
                ContextUtil.getContext().toastShort("删除失败，请重试")
            }

            override fun onSuccess(data: String?) {
                mMsgManager.deleteMessageFromLocalStorage(
                    object : OnBase<String> {
                        override fun onError(code: Long, error: String?) {}

                        override fun onSuccess(data: String?) {
                            ContextUtil.getContext().toastShort("已删除")
                        }
                    }, msg
                )
            }
        }, listOf(msg))
    }


    // 播放语音计时器
    var voicePlayCountDownTimer: CountDownTimer? = null

    // 当前语音消息
    private var currentVoiceMsg: Message? = null
    fun getCurrentVoiceMsg() = currentVoiceMsg

    // 语音消息时长
    private val _voicePlayDuration: MutableLiveData<Int> = MutableLiveData(0)
    val voicePlayCountDown: LiveData<Int> get() = _voicePlayDuration

    // 语音播放状态
    private var _voicePlayState = false
    fun getVoicePlayState() = _voicePlayState

    // 点击播放语音消息的事件
    fun onVoiceItemClick(msg: Message) {
        SLog.d(this.TAG(), "${msg.soundElem.duration}  click")
        if (_voicePlayState) {
            stopPlayVoice(msg)
        } else {
            startPlayVoice(msg)
        }
    }

    fun startPlayVoice(msg: Message) {
        SLog.d(this.TAG(), "prepare")
        currentVoiceMsg = msg
        _voicePlayState = true
        var duration = msg.soundElem.duration.toInt() * 2
        _voicePlayDuration.postValue(duration)
        voicePlayCountDownTimer = object : CountDownTimer(msg.soundElem.duration * 1000L, 500) {
            override fun onTick(millisUntilFinished: Long) {
                SLog.d(this.TAG(), "tick")
                _voicePlayDuration.postValue(duration--)
            }

            override fun onFinish() {
                onPlayVoiceFinish()
            }
        }
        voicePlayCountDownTimer?.start()
        SLog.d(this.TAG(), "start")
        viewModelScope.launch {
            RecordVoiceUtil.startPlayRecord(msg) {
                onPlayVoiceFinish()
            }
        }
    }

    private fun onPlayVoiceFinish() {
        SLog.d(this.TAG(), "finish")
        _voicePlayState = false
        voicePlayCountDownTimer = null
        _voicePlayDuration.postValue(-1)
    }

    fun stopPlayVoice(msg: Message) {
        SLog.d(this.TAG(), "stop")
        viewModelScope.launch {
            voicePlayCountDownTimer?.cancel()
            RecordVoiceUtil.stopPlayRecord()
            onPlayVoiceFinish()
            _voicePlayState = false
        }
    }

}


class ChatUiState(
    var friendId: String,
    var friendName: String,
    val initMsgList: List<Message>
) {
    private val _msgList: MutableList<Message> =
        mutableStateListOf(*initMsgList.toTypedArray())

    val msgList: List<Message> get() = _msgList

    fun setMsgList(list: List<Message>) {
        _msgList.clear()
        _msgList.addAll(list)
    }

    fun addMsg(msg: Message) {
        _msgList.add(0, msg)
    }

    fun removeMsg(msg: Message) {
        _msgList.remove(msg)
    }
}

data class ExtendInputBean(
    val name: String,
    val imgIdRes: Int,
    val clickEvent: () -> Unit
)